/*
 * Flashlib - QB9 common Flash library
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */


package com.qb9.flashlib.easing
{
	import com.qb9.flashlib.tasks.*;

	/**
	 * Generic easing task.  This task will call a given update function on each time step.
	 * 
	 * <p>Example: 
	 * <pre>
	 * var ease:Ease = new Ease(trace, 500, 10.0, 20.0);
	 * </pre>
	 * When added to an TaskRunner, for 0.5 seconds the output will be something like:
	 * <pre>
	 * 10.0
	 * 10.0008232
	 * 10.0056928
	 * ...
	 * 19.9991920
	 * 19.9999013
	 * 20.0
	 * </pre>
	 * </p>
	 *
	 * @see TaskRunner
	 * @see Tween
	 * @see Easing
	 */
	public class Ease extends TimeBasedTask
	{
		private var callback:Function;
		private var from:Number;
		private var change:Number;
		private var args:Array;
		private var easeFunction:Function;

		/**
		 * Create an Ease task.
		 *
		 * @param updateFunction The function that will be called for each time step.  It will be passed the current tween value (between <code>from</code> and <code>to</code>), and any additional arguments passed to the constructor.
		 * @param duration Duration (in milliseconds) for the task.
		 * @param from Initial easing value.
		 * @param to Destination easing value.
		 * @param transition Any identifier accepted by <code>Easing.getFunction()</code>. Examples: "linear" (default), "easeIn", "easeOut", "easeInOut", "bounceEaseIn", etc.
		 *
		 * @see com.qb9.flashlib.tasks.TaskRunner
		 * @see Easing
		 */
		public function Ease(updateFunction:Function, duration:int, from:Number = 0.0, to:Number = 1.0, transition:String = "linear", ... args)
		{
			super(duration);
			this.callback = updateFunction;
			this.args = args;
			this.from = from;
			this.change = to - from;
			this.easeFunction = Easing.getFunction(transition);
		}

		/** @inheritDoc */
		public override function clone():ITask
		{
			var ease:Ease = new Ease(callback, duration);
			ease.args = args;
			ease.from = from;
			ease.change = change;
			ease.easeFunction = easeFunction;
			return ease;
		}

		/** @inheritDoc */
		protected override function updateState():void
		{
			var tween:Number = this.easeFunction(this.elapsed, from, change, this.duration);
			this.callback.apply(null, [tween].concat(this.args));
		}
	}
}

